#include "fonction.h"

float vitesseVoulue; //Stocke la vitesse voulue pour commander le tapis
double vitesseLue; //Stocke la vitesse lue du tapis (vitesse réel !)
float inclinaison = 0; //Position initiale du tapis, variable globale qui stocke sa position
float inclinaisonVoulue; //Stocke l'inclinaison voulue par l'utilisateur

void tapis(){
  /*
  //Exemple de la lecture de la vitesse en km/h
  vitesseLue = lectureVitesse(); //Lecture de la vitesse du tapis en lancant la fonction
  Serial.print(vitesseLue); //Affichage de la vitesse
  Serial.println(" km/h"); //Retour à la ligne
  delay(2000); //Attente avant une autre lecture
  */
  
  /*
  //Exemple de commande de la vitesse
  Serial.println("Vitesse Voulue ? (MAX : 23 km/h !)"); //Affichage de cette chaîne de caractère
    while(Serial.available() != 1){}  //Attente pour recevoir la vitesse
  vitesseVoulue = Serial.parseFloat(); //Récupération de la vitesse
  Serial.println(vitesseVoulue); //Affichage de la vitesse voulue
  commandeVitesse(vitesseVoulue); //Lance la fonction commandeVitesse avec la vitesse voulue
  */
  
  /*
  //Exemple de commande de l'inclinaison
  Serial.println("Inclinaison Voulue ? (MAX : 10 % !)"); //Affichage de cette chaîne de caractère
  while(Serial.available() != 1){} //Attente pour recevoir l'inclinaison voulue
  inclinaisonVoulue = Serial.parseFloat(); //Récupération de l'inclinaison voulue
  Serial.println(inclinaisonVoulue); //Affichage de l'inclinaison voulue (ln après print permet retour à la ligne)
  commandeInclinaison(inclinaisonVoulue); //Lance la fonction commandeInclinaison avec l'inclinaison voulue
  */
}

double lectureVitesse() { //Fonction lectureVitesse, retourne la vitesse en type double
  unsigned long temps; //permettra le calcul du temps entre 2 impulsions de l'ILS
  double perimetre = 0.135; //Perimetre du rouleau du tapis
  double vitesse; //Stocke la vitesse, vitesse sera retourné par la fonction
  
  //Algorithme pour lire la vitesse (voir l'étude du signal de l'ILS
  if(digitalRead(2) != HIGH){ //Si le capteur est à l'état bas
    while(digitalRead(2) != HIGH){ //Tant que capteur à état bas, attendre
    
    }
    temps = micros(); //Front montant donc on prend la valeur du temps
    while(digitalRead(2) == HIGH){//Attente du front descendant
      //aimant toujours devant le capteur
    }
    while(digitalRead(2) != HIGH){//Attente du front montant
      //aimant n'est pas devant ILS
    }
    temps = micros() - temps;  //Temps entre 2 fronts montant
  }
  else{ //Capteur à l'état haut
    while(digitalRead(2) == HIGH){//Attente du front descendant
      //ne rien faire, aimant devant le capteur
    }
    temps = micros(); //Front descendant donc démarrage chrono
    while(digitalRead(2) != HIGH){ //Attente du front montant
      //aimant n'est pas devant le capteur
    }
    while(digitalRead(2) == HIGH){ //Attente front descendant
      // aimant devant ILS
    }
    temps = micros() - temps; //Fin du chrono
  }
  vitesse = 3.6 * perimetre * 1000000 / temps; // Vitesse = Distance divisé par Temps
  return vitesse; //Retourne la vitesse
  
  
  //Aide mémoire sur la lecture des entrées analogues
  /*
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
  */  
}

void commandeVitesse(float vitesse){ //Fonction commandeVitesse, permet de régler la vitesse du tapis
  int cycle = vitesse*1.9 + 5.3; //équation reliant la vitesse du tapis et le cycle (tON) du signal (c.f. étude signal de commande vitesse)
  //équation à mieux déterminer !
  
  while(1){ //Boucle tant que (ici boucle infini !), permet la multiplicité de la période
    pwm(pinCommandeVitesse, 50, cycle); //Lance la fonction PWM(pin, periode, cycle)
  }
}

void pwm(int pin, int periode, int cycle){  //Fonction PWM implémenté par mes soins
  //Algorithme de la fonction pour créer une période élémentaire
  digitalWrite(pin, HIGH); //état haut
  delay(cycle);  //tON en ms
  digitalWrite(pin, LOW);  //état bas
  delay(periode-cycle);  //tOFF en ms
}

void commandeInclinaison(float inclinaisonVoulue){ //Fonction pour commander l'inclinaison
  if(inclinaisonVoulue > inclinaison){ //Si l'inclinaison voulue est supérieure à l'inclinaison du tapis
    digitalWrite(pinCommandeInclinaisonMontee, HIGH); //On monte le tapis en mettant le pin à l'état haut
    while(inclinaison != inclinaisonVoulue){ //Tant que l'inclinaison ne correspond pas à celle voulue
      lectureInclinaison(); //Lecture de l'inclinaison
    }
    digitalWrite(pinCommandeInclinaisonMontee, LOW); //L'inclinaison est celle voulue, on arrete la montée
  }
  if(inclinaisonVoulue < inclinaison){ //Si l'inclinaison voulue est inférieure à celle du tapis
    digitalWrite(pinCommandeInclinaisonDescente, HIGH); //On descend le tapis en mettant le pin correspondant à l'état haut
    while(inclinaison != inclinaisonVoulue){ //Tant que l'inclinaison n'est pas celle voulue
      lectureInclinaison();  //Lecture de l'inclinaison
    }
    digitalWrite(pinCommandeInclinaisonDescente, LOW); //L'inclinaison est celle voulue, on arrete la descente du tapis
  }
}

void lectureInclinaison(){ //Lecture de l'inclinaison du tapis, la fonction modifie une variable globale inclinaison
  if(digitalRead(pinCommandeInclinaisonMontee) == HIGH && digitalRead(pinCommandeInclinaisonDescente) == LOW && digitalRead(pinLectureInclinaison) == HIGH){ //Si le tapis monte et si on relève une impulsion du capteur
    inclinaison = inclinaison + 0.125; //On augmente la valeur de l'inclinaison
    while(digitalRead(pinLectureInclinaison) == HIGH){ //Tant que capteur à état haut, attendre
    
    }
  }
  else if(digitalRead(pinCommandeInclinaisonMontee) == LOW && digitalRead(pinCommandeInclinaisonDescente) == HIGH && digitalRead(pinLectureInclinaison) == HIGH){ //Si le tapis descend et si on relève une impulsion du capteur
    inclinaison = inclinaison - 0.125; //On diminue la valeur de l'inclinaison
    while(digitalRead(pinLectureInclinaison) == HIGH){ //Tant qu'il y a l'état haut
      
    }
  }
}
